<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="550" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.fillStyle = 'black';

        // Cylinder parameters
        const centerX = 275;
        const centerY = 150;
        const cylinderRadius = 45;
        const cylinderLength = 320;
        const cylinderLeftX = centerX - cylinderLength / 2;
        const cylinderRightX = centerX + cylinderLength / 2;
        const cylinderPerspectiveRadius = 20; // for the left ellipse cap

        // Draw Cylinder
        ctx.beginPath();
        // Top and bottom lines
        ctx.moveTo(cylinderLeftX, centerY - cylinderRadius);
        ctx.lineTo(cylinderRightX, centerY - cylinderRadius);
        ctx.moveTo(cylinderLeftX, centerY + cylinderRadius);
        ctx.lineTo(cylinderRightX, centerY + cylinderRadius);
        // Right end cap (semicircle)
        ctx.arc(cylinderRightX, centerY, cylinderRadius, -Math.PI / 2, Math.PI / 2);
        ctx.stroke();
        // Left end cap (ellipse for 3D effect)
        ctx.beginPath();
        ctx.ellipse(cylinderLeftX, centerY, cylinderPerspectiveRadius, cylinderRadius, 0, 0, 2 * Math.PI);
        ctx.stroke();

        // Coil parameters
        const numLoops = 8;
        const loopWidth = 30;
        const coilStartX = cylinderLeftX + 50;

        // Draw Coil
        ctx.beginPath();
        // Draw the vertical lines representing the front of the rope
        for (let i = 0; i <= numLoops; i++) {
            const xPos = coilStartX + i * loopWidth;
            ctx.moveTo(xPos, centerY - cylinderRadius);
            ctx.lineTo(xPos, centerY + cylinderRadius);
        }
        ctx.stroke();

        ctx.beginPath();
        // Draw top and bottom semicircle-like arcs
        for (let i = 0; i < numLoops; i++) {
            const loopCenterX = coilStartX + i * loopWidth + loopWidth / 2;
            // Top semicircle
            ctx.moveTo(loopCenterX - loopWidth / 2, centerY - cylinderRadius);
            ctx.arc(loopCenterX, centerY - cylinderRadius, loopWidth / 2, Math.PI, 2 * Math.PI);
            // Bottom semicircle
            ctx.moveTo(loopCenterX + loopWidth / 2, centerY + cylinderRadius);
            ctx.arc(loopCenterX, centerY + cylinderRadius, loopWidth / 2, 0, Math.PI);
        }
        ctx.stroke();

        // Masses and Strings parameters
        const boxSize = 50;
        const stringLength = 100;
        const massTopY = centerY + cylinderRadius + stringLength;

        // Mass m (left)
        const m_hang_x = coilStartX + loopWidth; // Hang from the 2nd vertical line
        ctx.beginPath();
        ctx.moveTo(m_hang_x, centerY + cylinderRadius);
        ctx.lineTo(m_hang_x, massTopY);
        ctx.stroke();
        ctx.beginPath();
        ctx.rect(m_hang_x - boxSize / 2, massTopY, boxSize, boxSize);
        ctx.stroke();

        // Mass M (right)
        const M_hang_x = coilStartX + (numLoops - 1) * loopWidth; // Hang from the 2nd to last vertical line
        ctx.beginPath();
        ctx.moveTo(M_hang_x, centerY + cylinderRadius);
        ctx.lineTo(M_hang_x, massTopY);
        ctx.stroke();
        ctx.beginPath();
        ctx.rect(M_hang_x - boxSize / 2, massTopY, boxSize, boxSize);
        ctx.stroke();
        
        // Labels and Caption
        ctx.font = "italic 30px 'Times New Roman'";
        ctx.textBaseline = "middle";

        // Label 'm'
        ctx.textAlign = "right";
        ctx.fillText("m", m_hang_x - boxSize / 2 - 10, massTopY + boxSize / 2);
        
        // Label 'M'
        ctx.textAlign = "left";
        ctx.fillText("M", M_hang_x + boxSize / 2 + 10, massTopY + boxSize / 2);

        // Caption
        ctx.font = "28px 'KaiTi'"; // A common Chinese font
        ctx.textAlign = "center";
        ctx.fillText("力图 2.1.1", centerX, canvas.height - 30);
    </script>
</body>
</html>